package com.mfin.bs.mappers.impl;

import com.mfin.bs.mappers.factory.BaseMapperFactory;
import com.mfin.bs.mappers.factory.IMapperFactory;
import com.mfin.bs.mappers.interfaces.IMapper;
import com.mfin.log.Logger;
import com.mfin.vo.interfaces.IIdentifiableObject;
import com.mfin.vo.interfaces.IMappable;

public abstract class BaseMapper extends Logger implements IMapper {
	IMapperFactory mapperFactory = BaseMapperFactory.getInstance();

	@Override
	public boolean map(IMappable fromArg, IMappable toArg,
			boolean validateKeys, boolean mapKeys) {

		if (fromArg instanceof IIdentifiableObject
				&& toArg instanceof IIdentifiableObject) {
			mapIdentifiable((IIdentifiableObject) fromArg,
					(IIdentifiableObject) toArg, validateKeys, mapKeys);
		}
		if (doMap(fromArg, toArg)) {
			return true;
		} else {
			IMapper mapper = mapperFactory.getMapper(fromArg, toArg);

			if (mapper == null || mapper.equals(this)) {
				return false;
			}
			return mapper.map(fromArg, toArg, validateKeys, mapKeys);
		}
	}

	protected abstract boolean doMap(IMappable fromArg, IMappable toArg);

	public void mapIdentifiable(IIdentifiableObject fromArg,
			IIdentifiableObject toArg, boolean validateKeys, boolean mapKeys) {
		if (validateKeys) {
			if (fromArg.getKeys() == null) {
				// throw exception
			}
		}
		if (mapKeys) {
			toArg.setKeys(fromArg.getKeys());
		}
	}
}
